package com.eric.media;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.audiofx.BassBoost;
import android.media.audiofx.Equalizer;
import android.media.audiofx.PresetReverb;
import android.media.audiofx.Visualizer;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.TextView;

import org.androidannotations.annotations.AfterInject;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;

import java.util.ArrayList;
import java.util.List;

/**
 * 音乐的示波器、均衡、重低音和音场示例
 */
@EActivity(R.layout.activity_audio_effect)
public class AudioEffectActivity extends Activity {
    /**定义播放声音的MediaPlayer*/
    private MediaPlayer mPlayer;
    /**定义系统示波器*/
    private Visualizer mVisualizer;
    /**定义系统的均衡器*/
    private Equalizer mEqualizer;
    /**定义系统的重低音控制器*/
    private BassBoost mBassBoost;
    /**定义系统的预设音控制器*/
    private PresetReverb mpresetReverb;
    @ViewById(R.id.lLayout)
    LinearLayout linearLayout;
    private List<Short> reverbNames = new ArrayList<>();
    private List<String> reverVals = new ArrayList<>();

    /**
     * 该方法会在onCreate方法中调用
     */
    @AfterInject
    void inject(){
        setVolumeControlStream(AudioManager.STREAM_MUSIC);
    }
    /**
     * 该方法会在setContentView方法中调用
     */
    @AfterViews
    void initData(){
        //设置控制音乐声音
//        linearLayout = new LinearLayout(this);
//        linearLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
//                ViewGroup.LayoutParams.MATCH_PARENT));
//        linearLayout.setOrientation(LinearLayout.VERTICAL);
//        setContentView(linearLayout);
        mPlayer = MediaPlayer.create(this,R.raw.hongyanjiu);
        mPlayer.setLooping(true);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == -1
                    || ActivityCompat.checkSelfPermission(this,Manifest.permission.MODIFY_AUDIO_SETTINGS) == -1){
                ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECORD_AUDIO,
                        Manifest.permission.MODIFY_AUDIO_SETTINGS},0x123);
            }else {
                //初始化示波器
                setupVisualizer();
                setupEqualizer();
                setupPreseReverb();
                setupBassBoost();
                mPlayer.start();
            }
        }else {
            //初始化示波器
            setupVisualizer();
            setupEqualizer();
            setupPreseReverb();
            setupBassBoost();
            mPlayer.start();
        }

    }

//    @Override
//    protected void onCreate(Bundle savedInstanceState) {
//        super.onCreate(savedInstanceState);
//
//    }


    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 0x123){
            if (grantResults[0] == 0){
                //初始化示波器
                setupVisualizer();
                setupEqualizer();
                setupPreseReverb();
                setupBassBoost();
                mPlayer.start();
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (isFinishing() && mPlayer != null) {
            // 释放所有对象
            mVisualizer.release();
            mEqualizer.release();
            mpresetReverb.release();
            mBassBoost.release();
            mPlayer.release();
            mPlayer = null;
        }
    }
    /**
     * 初始化重低音控制器
     */
    private void setupBassBoost() {
        mBassBoost = new BassBoost(0,mPlayer.getAudioSessionId());
        mBassBoost.setEnabled(true);
        TextView bbTitle = new TextView(this);
        bbTitle.setText("重低音");
        linearLayout.addView(bbTitle);
        SeekBar bar = new SeekBar(this);
        //重低音的范围0～1000
        bar.setMax(1000);
        bar.setProgress(0);
        bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                mBassBoost.setStrength((short) progress);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        linearLayout.addView(bar);

    }


    /**
     *  初始化预设音场控制器
     */
    private void setupPreseReverb() {

        mpresetReverb = new PresetReverb(0,mPlayer.getAudioSessionId());
        mpresetReverb.setEnabled(true);
        TextView bbTitle = new TextView(this);
        bbTitle.setText("音场");
        linearLayout.addView(bbTitle);
        for (short i = 0; i < mEqualizer.getNumberOfPresets(); i++) {
            reverbNames.add(i);
            reverVals.add(mEqualizer.getPresetName(i));
        }

        Spinner spinner = new Spinner(this);
        spinner.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,reverVals));
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                //设置音场
                mpresetReverb.setPreset(reverbNames.get(position));
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
        linearLayout.addView(spinner);
    }


    /**
     * 初始化均衡控制器
     */
    private void setupEqualizer() {

        mEqualizer = new Equalizer(0,mPlayer.getAudioSessionId());
        mEqualizer.setEnabled(true);

        TextView eqTitle = new TextView(this);
        linearLayout.addView(eqTitle);
        final short minEQLevel = mEqualizer.getBandLevelRange()[0];
        short maxEQLevel = mEqualizer.getBandLevelRange()[1];
        //获取均衡器支持的所用频率
        final short brands = mEqualizer.getNumberOfBands();
        for (short i = 0; i < brands; i++) {
            TextView eqtextView = new TextView(this);
            //创建一个View 用来显示频率
            eqtextView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
            eqtextView.setGravity(Gravity.CENTER_HORIZONTAL);
            //设置该均衡控制器的频率
            eqtextView.setText((mEqualizer.getCenterFreq(i) / 1000) + "Hz" );
            linearLayout.addView(eqtextView);
            //创建一个水平排列组件的线程布局
            LinearLayout tmpLayout = new LinearLayout(this);
            tmpLayout.setOrientation(LinearLayout.HORIZONTAL);
            //创建显示均衡控制器最小值的TextVIew
            TextView minDbTxt = new TextView(this);
            minDbTxt.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
            //显示最小值
            minDbTxt.setText(minEQLevel / 100 + "dB");

            //创建显示均衡控制器最大值的TextVIew
            TextView maxDbTxt = new TextView(this);
            maxDbTxt.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
            //显示最小值
            maxDbTxt.setText(maxEQLevel / 100 + "dB");

            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            layoutParams.weight = 1;
            //定义SeekBar作为调整工具
            SeekBar bar = new SeekBar(this);
            bar.setLayoutParams(layoutParams);
            bar.setMax(mEqualizer.getBandLevel(i));
            final short brand = i;
            bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                    //设置该频率的均衡值
                    mEqualizer.setBandLevel(brand, (short) (progress + minEQLevel));
                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {

                }

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {

                }
            });
            tmpLayout.addView(minDbTxt);
            tmpLayout.addView(bar);
            tmpLayout.addView(maxDbTxt);
            linearLayout.addView(tmpLayout);
        }

    }

    /**
     * 初始化示波器
     */
    private void setupVisualizer() {
        final MyVisualizerView myVisualizerView = new MyVisualizerView(this);
        myVisualizerView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                (int) (120f * getResources().getDisplayMetrics().density)));
        linearLayout.addView(myVisualizerView);
        //以mPlayer的AudioSessionId创建音频数据 相当于设置Visualizer负责mPlayer的音频数据
        mVisualizer = new Visualizer(mPlayer.getAudioSessionId());
        mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
        //设置监听
        mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
            @Override
            public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
//                用 waveform 更新波形数据更新myVisualizerView组件
                myVisualizerView.updateVisualizer(waveform);
            }

            @Override
            public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
//
            }
        },Visualizer.getMaxCaptureRate() /2 ,true, false);
        mVisualizer.setEnabled(true);
    }



    private static class MyVisualizerView extends View{
        /**bytes数组保存了波形抽样点的值*/
        private byte[] bytes;
        private float[] points;
        private Paint paint = new Paint();
        private Rect rect = new Rect();
        private byte type = 0;

        public MyVisualizerView(Context context) {
            super(context);
            bytes = null;
            paint.setStrokeWidth(1f);
            paint.setAntiAlias(true);
            paint.setColor(Color.GREEN);
            paint.setStyle(Paint.Style.FILL);
        }
        public void updateVisualizer(byte[] fitt){
            bytes = fitt;
            invalidate();
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            //当用户触摸该组件，切换波形类型
            if (event.getAction() != MotionEvent.ACTION_DOWN){
                return false;
            }
            type ++;
            if (type >= 3){
                type = 0;
            }
            return true;
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if (bytes == null){
                return;
            }
            canvas.drawColor(Color.WHITE);
            rect.set(0,0,getWidth(),getHeight());
            switch (type){
                case 0://绘制块状的波形图
                    for (int i = 0; i < bytes.length -1 ; i++) {
                        float left = getWidth()*i/(bytes.length -1);
                        //根据波形值计算该矩形高度
                        float top = rect.height() - (byte)(bytes[i + 1] + 128) * rect.height() /128;
                        float right = left + 1;
                        float bottom = rect.height();
                        canvas.drawRect(left,top,right,bottom,paint);
                    }
                    break;
                case 1://绘制柱状的波形图
                    for (int i = 0; i < bytes.length -1 ; i++) {
                        float left = rect.width() / (bytes.length -1);
                        //根据波形值计算该矩形高度
                        float top = rect.height() - (byte)(bytes[i + 1] + 128) * rect.height() /128;
                        float right = left + 6;
                        float bottom = rect.height();
                        canvas.drawRect(left,top,right,bottom,paint);
                    }
                    break;
                case 2://绘制曲线波形图
                    if (points == null || points.length < bytes.length * 4){
                        points = new float[bytes.length * 4];
                    }
                    for (int i = 0; i < bytes.length - 1; i++) {
                        //计算第i个点的x坐标
                        points[i * 4] = rect.width() / (bytes.length -1);
                        //计算bytes[i]的值（波形点的值）计算第i个点的y坐标
                        points[i * 4 + 1] = (rect.height() / 2) + (byte)(bytes[i + 1] + 128) * 128  / rect.height() / 2;
                        //计算 i + 1 个点的x坐标
                        points[i * 4 + 2] = rect.width() * (i + 1) / (bytes.length - 1);
                        //计算 i + 1 个点的y坐标
                        points[i * 4 + 3] = (rect.height() / 2) + (byte)(bytes[i + 1] + 128) * 128  / rect.height() / 2;
                        canvas.drawLines(points,paint);
                    }
                    break;
            }
        }


    }



}
